/*
 * Ganesa Copyright (C) 2008 Wim Crols <twimpiex@gnx.be>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package be.gnx.ganesa.plugin.gpx.command;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import be.gnx.ganesa.application.model.Application;
import be.gnx.ganesa.application.model.Layer;
import be.gnx.ganesa.application.plugin.ImportPlugin;
import be.gnx.ganesa.application.ui.dialog.ImportDialog.ImportDialogResult;
import be.gnx.ganesa.plugin.gpx.model.GPX;
import be.gnx.ganesa.plugin.gpx.model.WayPoint;

public class ImportCommand extends be.gnx.ganesa.application.command.ImportCommand {

  public ImportCommand(Application application, ImportDialogResult importDialogResult, ImportPlugin importPlugin) {
    super(application, importDialogResult, importPlugin);
  }

  @Override
  public void execute(Vector<Layer> layers) {
    for (Layer layer : layers) {
      if (layer instanceof GPX) {
        final GPX gpxLayer = (GPX) layer;
        long previousNumberOfWayPoints = -1;
        long currentNumberOfWayPoints = gpxLayer.getNodes().size();
        int pageNumber = -1;
        while (previousNumberOfWayPoints < currentNumberOfWayPoints) {
          pageNumber++;
          try {
            URL url = new URL("http", "api.openstreetmap.org", 80, "/api/0.5/trackpoints?bbox="
                + Math.toDegrees(getBoundingBox().getBottomLeftCoordinate().getLongitude()) + ","
                + Math.toDegrees(getBoundingBox().getBottomLeftCoordinate().getLatitude()) + ","
                + Math.toDegrees(getBoundingBox().getTopRightCoordinate().getLongitude()) + ","
                + Math.toDegrees(getBoundingBox().getTopRightCoordinate().getLatitude()) + "&page=" + pageNumber);
            getProject().setZoomBox(getBoundingBox());
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
            InputStream inputStream = urlConnection.getInputStream();
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            parser.parse(inputStream, new DefaultHandler() {
              private WayPoint wayPoint = null;
              private long startId = gpxLayer.getNodes().size();
              private long id = 0;

              @Override
              public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
                if (name.equals("trkpt")) {
                  id++;
                  wayPoint = gpxLayer.newWayPoint(startId + id, Math.toRadians(Double.parseDouble(attributes.getValue("lat"))), Math.toRadians(Double
                      .parseDouble(attributes.getValue("lon"))), 0);
                  wayPoint.addAttribute("ganesa", "ganesa");
                }
                super.startElement(uri, localName, name, attributes);
              }

              @Override
              public void endElement(String uri, String localName, String qName) throws SAXException {
                if (qName.equals("trkpt")) {
                  wayPoint = null;
                }
                super.endElement(uri, localName, qName);
              }

            });
            urlConnection.disconnect();
          } catch (MalformedURLException malformedURLException) {
            System.err.println(malformedURLException);
          } catch (IOException ioException) {
            System.err.println(ioException);
          } catch (ParserConfigurationException parserConfigurationException) {
            System.err.println(parserConfigurationException);
          } catch (SAXException saxException) {
            System.err.println(saxException);
          }
          previousNumberOfWayPoints = currentNumberOfWayPoints;
          currentNumberOfWayPoints = gpxLayer.getNodes().size();
        }
      }
    }
  }

  @Override
  public String displayString() {
    return "import from ...";
  }

}
